/*
 *  CellularAutomation.h
 *  
 *
 *  Created by Daniel Condon on 25/07/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

#include "Cell.h"
#include "../Creatures/Creature/Creature.h"



class CellularAutomation{
private:
	int width, height;
	
	gsl_rng * r;
	
	Creature creatures;
	Cell*** cell;
	
	
	int x, y;
public:
	/*--Default Constructor
	 builds a 1 cell matrix
	 */
	CellularAutomation();
	
	/*--Main Constructor
	 Builds the array columns->rows
	 Params
	 Parameter(0) : number of columns in the matrix
	 Parameter(1) : number of rows in the matrix
	 Parameter(2) : default creature for cellular automata
	*/
	CellularAutomation(int, int, Creature);
	
	/*--Deconstructor
	 Builds the array columns->rows
	 Params
	 Parameter(0) : number of columns in the matrix
	 Parameter(1) : number of rows in the matrix
	 Parameter(2) : default creature for cellular automata
	 */
	~CellularAutomation();
	
	/*--This function will seed a cell with some initial migrants
	 Params
	 Parameter(0) : x coordinate of the cell
	 Parameter(1) : y coordinate of the cell
	 Parameter(2) : number of migrants to initiate with
	 Pre : Param(0&1) valid number within the array bounds
			Param(2) valid number less than the maximum cell
	 */
	void seedCell(int, int, int);
	
	/*--This function returns the matrix width
	 Returns : matrix max x value
	 */
	int getWidth();
	
	/*--This function returns the matrix height
	 Returns : matrix max y value
	 */
	int getHeight();
	
	/*--Returns the Cell at a given point
	 Params:
	 Parameter(0) : x coordinate of the cell
	 Parameter(1) : y coordinate of the cell
	 Pre : Parameter(0&1) not NULL and within the bounds of the matrix
	 Returns : Cell at point Parameter(0):Parameter(1)
	 */	
	Cell* getCell(int, int);
	
	/*--This function returns the current creatures in the cell
	 Params:
	 Parameter(0) : x coordinate of the cell
	 Parameter(1) : y coordinate of the cell
	 Pre : Parameter(0&1) not NULL and within the bounds of the matrix
	 Returns : Cell population at point Parameter(0):Parameter(1)
	 */	
	int getCellCurrent(int, int);
	
	/*--This function returns the maximum creatures for the cell
	 Params:
	 Parameter(0) : x coordinate of the cell
	 Parameter(1) : y coordinate of the cell
	 Pre : Parameter(0&1) not NULL and within the bounds of the matrix
	 Returns : Cell population maximum at point Parameter(0):Parameter(1)
	 */	
	int getCellMax(int, int);
	
	/*--This function approximates the barriers and 
		whether the migration event can progress
	 Params:
	 Parameter(0) : x coordinate of the cell
	 Parameter(1) : y coordinate of the cell
	 Parameter(2) : degrees from 0(left or side a) the migration event indends to travel
	 Pre : Parameter(0&1) not NULL and within the bounds of the matrix
	 Returns : If the migration event connects with a wall
	 
	 NOTE : will need to convert this to actual line calculations
	 */	
	bool Check(int, int, double);
	
	/*--This function detirmines the direction of the migration event
	 Params:
	 Parameter(0) : gsl random number generator
	 Parameter(1) : x coordinate of the cell
	 Parameter(2) : y coordinate of the cell
	 Pre : Parameter(0&1) not NULL and within the bounds of the matrix
	 Returns : direction in degrees the migration event will occur
	 */
	double DetirmineDirection(gsl_rng*, int, int);
	
	/*--This function detirmines the distance of the migration event
	 Params:
	 Parameter(0) : gsl random number generator
	 Returns : distance the migration event will travel
	 */
	double MigrationRadius(gsl_rng*);
	
	/*--This function detirmines the number of migrats
	 Params:
	 Parameter(0) : gsl random number generator
	 Parameter(1) : x coordinate of the cell
	 Parameter(2) : y coordinate of the cell
	 Pre : Parameter(1&2) not NULL and within the bounds of the matrix
	 Returns : number of migrants in the migration event
	 */
	int MigrationSize(gsl_rng*,int, int);
	
	/*--This function will send migrants for each cell using DetirmineDirection
		MigrationRadius and MigrationSize to detirmine parameters for sending
	 */
	void MigrationCycle();
	
	/*--This function will receive migrants for each cell and add them to the
		current creatures in the cell
	 */
	void CompleteMigration();
	
	/*--This function will calculate growth within the cell using a poisson distribution
	 */
	void GrowthCycle();
	
	/*--This function will run the full cycle(MigrationCycle, CompleteMigration and GrowthCycle)
	 */
	void Cycle();
};